<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        // 作业1
        // function test(){
        //     function a(){
        //         var a = 2;
        //     }
        //     return a;
        //     a = 1;
        // }
        // console.log(test());
        
        // 作业2
        // console.log(test());
        // function test(){
        //     function a(){}
        //     a = 1;
        //     var a = 2;
        //     return a;
        // }

        // 作业3
        // a = 1;
        // function test(e){
        //     function e(){}
        //     arguments[0] = 2;
        //     console.log(e);
        //     if(a){
        //         var b = 3;
        //     }
        //     var c;
        //     a = 4;
        //     var a;
        //     console.log(b);
        //     f = 5;
        //     console.log(c);
        //     console.log(a);
        // }
        // var a;
        // test(1);
        // console.log(a);
        // console.log(f);
        
        
        /*********** 作用域&作用域链 ************/
        
        // AO -> function   独立的仓库
        // 什么是作用域
        // 先得说obj
        // var obj = {
        //     name: '蓝轨迹',
        //     address: '北京',
        //     teach: function(){}
        // }

        // console.log(obj.name);

        // 也是一种对象对象类型，引用类型，引用值
        // test.name test.length test.prototype
        // function test(){}
        // 对象 -> 有些属性是我们无法访问的
        //         JS引擎内部固有的隐式属性
        // [[scope]] 域
        // 1、函数创建时，生成的一个JS内部的隐式属性
        // 2、函数存储作用域链的容器 AO/GO
        //      AO,函数的执行期上下文
        //      GO,全局的执行期上下文
        //      函数执行完成之后，AO是要销毁的，
        //      AO是一个即时的存储容器
        
        // function a(){
        //     function b(){
        //         var  b = 2;
        //     }
        //     var a = 1;
        //     b();
        // }
        // var c = 3;
        // a();

        // 1、当a函数被定义的时候，系统生成[[scope]]属性，[[scope]]保存了
        //    该函数的作用域链，该作用域链顶部存储着全局执行上下文GO，GO里
        //    存储全局下的所有对象，包含函数a和全局变量c
        // 2、当a函数被执行时(前一刻)，作用域链的顶端存储a函数的函数执行上
        //    下文AO，往下存储着GO。查找变量是到a函数存储的作用域链中从顶端
        //    开始依次向下查找
        // 3、当b函数被定义时，是在a函数环境下，所以b函数这时的作用域链就是
        //    a函数被执行期上下文的作用域链
        // 4、当b函数被执行时(前一刻)，生成函数b的[[scope]]，存储函数b作用
        //    ，顶端存储b函数的AO，a函数的AO和全局的GO依次向下排列
        // 5、当b函数被执行结束后，b函数AO销毁，回归被定义状态
        // 6、当a函数被执行结束后，b函数整个作用域都被销毁，a函数AO销毁，回归被定义状态
        // 7、当全局中的a函数执行完之后，整个a作用域销毁
    
        // 简单的说：
        // 函数被定义已经形成了[[scope]] -> scope chain -> GO
        // 函数被执行那一刻生成AO

        // 例子：
        function a(){
            function b(){
                function c(){

                }
                c();
            }
            b();
        }
        a();

        // a定义：a.[[scope]] -> scope chain -> 0 : GO
        // a执行：a.[[scope]] -> scope chain -> 0 : a -> AO
        //                                      1 : GO
        // b定义：b.[[scope]] -> scope chain -> 0 : a -> AO
        //                                      1 : GO
        // b执行：b.[[scope]] -> scope chain -> 0 : b -> AO
        //                                      1 : a -> AO
        //                                      2 : GO
        // c定义：c.[[scope]] -> scope chain -> 0 : b -> AO
        //                                      1 : a -> AO
        //                                      2 : GO
        // c执行：c.[[scope]] -> scope chain -> 0 : c -> AO
        //                                      1 : b -> AO
        //                                      2 : a -> AO
        //                                      3 : GO
        // c结束：c.[[scope]] -> scope chain -> 0 : b -> AO
        //                                      1 : a -> AO
        //                                      2 : GO
        // b结束：b.[[scope]] -> scope chain -> 0 : a -> AO
        //                                      1 : GO
        // a结束：a.[[scope]] -> scope chain -> 0 : GO
    </script>
</body>
</html>